package pe.bf.extranet.dao.impl;

import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import oracle.jdbc.OracleTypes;
import pe.bf.base.dao.impl.BaseDAOImpl;
import pe.bf.base.types.OutParameter;
import pe.bf.domain.bean.Banco;
import pe.bf.domain.bean.Moneda;
import pe.bf.domain.bean.Transferencia;
import pe.bf.domain.exceptions.DomainException;
import pe.bf.extranet.dao.TransferenciaDAO;

public class TransferenciaDAOImpl extends BaseDAOImpl implements
		TransferenciaDAO {

	/*
	 * Constantes
	 */

	private static final String USP_CRE_TRANSFERENCIA = "{call PKG_TRANSFERENCIA.USP_CRE_TRANSFERENCIA(?,?,?,?,?,?,?,?)}";
	private static final String USP_ACT_TRANSFERENCIA = "{call PKG_TRANSFERENCIA.USP_ACT_TRANSFERENCIA(?)}";
	private static final String USP_LISTAR_TRANS_EMPRESA = "{call PKG_TRANSFERENCIA.USP_LISTAR_TRANS_EMPRESA(?,?,?)}";
	private static final String USP_LISTAR_TRANSFERENCIAS = "{call PKG_TRANSFERENCIA.USP_LISTAR_TRANSFERENCIAS(?,?)}";

	public TransferenciaDAOImpl(DataSource dataSource) {
		super(dataSource);
	}

	@Override
	public void crearTrasferencia(Transferencia transferencia)
			throws DomainException {
		try {
			invokeStoreProcedure(USP_CRE_TRANSFERENCIA, transferencia
					.getEmpresa().getIdEmpresa() + "", transferencia.getBanco()
					.getIdBanco() + "", transferencia.getMoneda().getIdMoneda()
					+ "", transferencia.getMonto(),
					transferencia.getNrocuenta(),
					transferencia.getNrooperacion(),
					transferencia.getUsuariocreacion(),
					transferencia.getFechatransferenciaString());

		} catch (DomainException e) {
			throw new DomainException(e);
		}
	}

	@Override
	public void aprobarTransferencia(Transferencia transferencia)
			throws DomainException {
		try {
			invokeStoreProcedureGetId(USP_ACT_TRANSFERENCIA,
					transferencia.getIdTransferencia());

		} catch (DomainException e) {
			throw new DomainException(e);
		}
	}

	@Override
	public void aprobarTransferenciaBatch(List<Transferencia> transferenciaList)
			throws DomainException {
		try {
			for (Transferencia transferencia : transferenciaList) {
				invokeStoreProcedureGetId(USP_ACT_TRANSFERENCIA,
						transferencia.getIdTransferencia());
			}
		} catch (DomainException e) {
			throw new DomainException(e);
		}
	}

	@Override
	public List<Transferencia> listarTranferenciaPorEmpresaPorEstado(
			Transferencia trans) throws Exception {
		List<Transferencia> lista = null;
		CallableStatement callableStatement = null;
		ResultSet resultSet = null;
		try {
			callableStatement = invokeStoreProcedureCallable(
					USP_LISTAR_TRANS_EMPRESA,
					trans.getEmpresa().getIdEmpresa(), trans.getEstado(),
					new OutParameter(OracleTypes.CURSOR));
			resultSet = (ResultSet) callableStatement.getObject(3);
			lista = new ArrayList<Transferencia>();
			while (resultSet.next()) {
				Transferencia transferencia = new Transferencia();
				transferencia.setIdTransferencia(resultSet
						.getLong("ID_TRANSFERENCIA"));
				transferencia.setFechacreacion(resultSet
						.getDate("FECHACREACION"));
				transferencia.setBanco(new Banco(resultSet.getLong("ID_BANCO"),
						resultSet.getString("BANCO")));
				transferencia.setNrocuenta(resultSet.getString("NROCUENTA"));
				transferencia.setNrooperacion(resultSet
						.getString("NROOPERACION"));
				transferencia.setFechatransferenciaString(resultSet
						.getString("FECHATRANSFERENCIASTRING"));
				transferencia.setMonto(resultSet.getBigDecimal("MONTO"));
				transferencia.setMoneda(new Moneda(resultSet
						.getLong("ID_MONEDA"), resultSet.getString("MONEDA")));
				transferencia.setUsuariocreacion(resultSet
						.getString("USUARIOCREACION"));
				transferencia.setFechatransferencia(resultSet
						.getDate("FECHATRANSFERENCIA"));
				transferencia.setEstado(resultSet.getString("ESTADO"));
				lista.add(transferencia);
			}
		} catch (SQLException e) {
			throw new DomainException(e);
		} finally {
			close(callableStatement.getConnection());
			close(callableStatement);
		}
		return lista;
	}

	@Override
	public List<Transferencia> listarTranferenciaPorEstado(Transferencia trans)
			throws Exception {
		List<Transferencia> lista = null;
		CallableStatement callableStatement = null;
		ResultSet resultSet = null;
		try {
			callableStatement = invokeStoreProcedureCallable(
					USP_LISTAR_TRANSFERENCIAS, trans.getEstado(),
					new OutParameter(OracleTypes.CURSOR));

			resultSet = (ResultSet) callableStatement.getObject(2);
			lista = new ArrayList<Transferencia>();
			while (resultSet.next()) {
				Transferencia transferencia = new Transferencia();
				transferencia.setIdTransferencia(resultSet
						.getLong("ID_TRANSFERENCIA"));
				transferencia.setFechacreacion(resultSet
						.getDate("FECHACREACION"));
				transferencia.setFechatransferencia(resultSet
						.getDate("FECHATRANSFERENCIA"));
				transferencia.setFechatransferenciaString(resultSet
						.getString("FECHATRANSFERENCIASTRING"));
				transferencia.setBanco(new Banco(resultSet.getLong("ID_BANCO"),
						resultSet.getString("BANCO")));
				transferencia.setNrocuenta(resultSet.getString("NROCUENTA"));
				transferencia.setNrooperacion(resultSet
						.getString("NROOPERACION"));
				transferencia.setMonto(new BigDecimal(resultSet
						.getLong("MONTO")));
				transferencia.setMoneda(new Moneda(resultSet
						.getLong("ID_MONEDA"), resultSet.getString("MONEDA")));
				transferencia.setUsuariocreacion(resultSet
						.getString("USUARIOCREACION"));
				transferencia.setEstado(resultSet.getString("ESTADO"));
				lista.add(transferencia);
			}
		} catch (SQLException e) {
			throw new DomainException(e);
		} finally {
			close(callableStatement.getConnection());
			close(callableStatement);
		}
		return lista;
	}

}
